﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foxit.PDF;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;
using Sustainalytics.Reporting.Framework;

namespace Sustainalytics.RiskRatings.Reporting
{
    public enum RangeChartType
    {
        Overview_RiskFramework,
        MEI_RatingDetails,
        MEI_IssueRiskExposure,
        MEI_Management
    }

    public class RiskRating_RangeBarChart : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }
        public float Width { get; set; }
        public double Value1 { get; set; }
        public double Value2 { get; set; }
        public double Value3 { get; set; }
        public double Value4 { get; set; }
        public float BarHeight { get; set; }
        public RangeChartType ChartType { get; set; }
        public string SubIndustryName { get; set; }
        public string CompanyName { get; set; }
        public float LeftBar { get; set; }
        public float TopBar { get; set; }

        private Group _elements;

        public void Render()
        {
            _elements = Elements();
        }

        private Group Elements()
        {
            var elements = new Group();
            float currentYOffset = Top;
            float startPos = Left + Width * 0.45f;
            float chartMaxWidth = Width * 0.55f;
            float dotSize = chartMaxWidth / (float)Math.Max(Value1, Value2);


            string firstBarText = string.Empty, secondBarText = string.Empty, thirdBarText = string.Empty;
            RgbColor firstBarColor = RgbColor.Pink, secondBarColor = RgbColor.Pink, thirdBarColor = RgbColor.Pink;
            float firstBarVerticalGap = BarHeight, secondBarVerticalGap = BarHeight;


            switch (ChartType)
            {
                case RangeChartType.Overview_RiskFramework:
                    {
                        firstBarText = "Exposure";
                        secondBarText = "Managed Risk";
                        thirdBarText = "Overall Unmanaged Risk";
                        firstBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.RiskExposure];
                        secondBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.ManagedRisk];
                        thirdBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.UnmanagedRisk];
                        firstBarVerticalGap = BarHeight / 2;
                        secondBarVerticalGap = BarHeight * 1.5f;
                    }; break;
                case RangeChartType.MEI_RatingDetails:
                    {
                        firstBarText = "Exposure";
                        secondBarText = "Managed Risk";
                        thirdBarText = "Unmanaged Risk";
                        firstBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.RiskExposure];
                        secondBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.ManagedRisk];
                        thirdBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.UnmanagedRisk];
                        firstBarVerticalGap = BarHeight / 2;
                        secondBarVerticalGap = BarHeight * 1.5f;
                    }; break;
                case RangeChartType.MEI_IssueRiskExposure:
                    {
                        firstBarText = string.Format("Exposure{0}({1})", Environment.NewLine, SubIndustryName);
                        secondBarText = string.Format("Exposure{0}({1})", Environment.NewLine, CompanyName.Length>25 ? CompanyName.Substring(0,21)+"...": CompanyName);
                        firstBarColor = secondBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.RiskExposure];
                        thirdBarColor = RgbColor.DarkCyan;
                        firstBarVerticalGap = BarHeight;
                        secondBarVerticalGap = BarHeight * 2f;
                    }; break;
                case RangeChartType.MEI_Management:
                    {
                        firstBarText = string.Format("Exposure{0}({1})", Environment.NewLine, CompanyName.Length > 25 ? CompanyName.Substring(0, 21) + "..." : CompanyName);
                        secondBarText = "Manageable Risk";
                        thirdBarText = "Managed Risk";
                        firstBarColor = secondBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.RiskExposure];
                        thirdBarColor = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.ManagedRisk];
                        firstBarVerticalGap = BarHeight;
                        secondBarVerticalGap = BarHeight;
                    }; break;
            }

            // first bar
            elements.Add(new TextArea(firstBarText,
                            Left,
                            currentYOffset - 3,
                            Width * 0.35f,
                            20f, Fonts.RobotoRegular, 7f, TextAlign.Right, RgbColor.Black));

            elements.Add(new Label(Value1.ToString("0.0"),
                            Left + Width * 0.35f,
                            currentYOffset - 3,
                            Width * 0.10f,
                            7f, Fonts.RobotoRegular, 7f, TextAlign.Center, RgbColor.Black));
            elements.Add(new Line(startPos, currentYOffset, startPos + (float)Value1 * dotSize, currentYOffset, BarHeight, firstBarColor));
            currentYOffset += BarHeight + firstBarVerticalGap;

            // second bar
            elements.Add(new TextArea(secondBarText,
                            Left,
                            currentYOffset - 3,
                            Width * 0.35f,
                            20f, Fonts.RobotoRegular, 7f, TextAlign.Right, RgbColor.Black));

            elements.Add(new Label(Value2.ToString("0.0"),
                            Left + Width * 0.35f,
                            currentYOffset - 3,
                            Width * 0.10f,
                            7f, Fonts.RobotoRegular, 7f, TextAlign.Center, RgbColor.Black));

            if (ChartType == RangeChartType.MEI_Management)
            {
                var displayValue = Math.Round((Value2 / Value1) * 100,1,MidpointRounding.AwayFromZero);

                elements.Add(new Label(displayValue.ToString("0.0") + "%",
                            startPos + (float)Value2 * dotSize + 5,
                            currentYOffset - 3,
                            50,
                            7f, Fonts.RobotoBold, 7f, TextAlign.Left, RgbColor.Black));
            }

            elements.Add(new Line(startPos, currentYOffset, startPos + (float)Value2 * dotSize, currentYOffset, BarHeight, secondBarColor));

            currentYOffset += BarHeight + secondBarVerticalGap;

            //third bar
            if (ChartType != RangeChartType.MEI_IssueRiskExposure)
            {
                elements.Add(new Label(thirdBarText,
                            Left,
                            currentYOffset - 3,
                            Width * 0.35f,
                            7f, Fonts.RobotoRegular, 7f, TextAlign.Right, RgbColor.Black));

                elements.Add(new Label(Value3.ToString("0.0"),
                                Left + Width * 0.35f,
                                currentYOffset - 3,
                                Width * 0.10f,
                                7f, Fonts.RobotoBold, 7f, TextAlign.Center, RgbColor.Black));
                if (ChartType == RangeChartType.MEI_Management)
                {
                    elements.Add(new Label(Value4.ToString("0.0") + "%",
                                startPos + (float)Value3 * dotSize + 5,
                                currentYOffset - 3,
                                50,
                                7f, Fonts.RobotoBold, 7f, TextAlign.Left, RgbColor.Black));
                }
            }

            if (ChartType == RangeChartType.MEI_Management)
            {
                elements.Add(new Line(startPos, currentYOffset, startPos + (float)Value3 * dotSize, currentYOffset, BarHeight, thirdBarColor));

                elements.Add(new Line(startPos + (float)Value3 * dotSize,
                                    currentYOffset + BarHeight / 2,
                                    startPos + (float)Value3 * dotSize,
                                    currentYOffset - BarHeight * 2.5f,
                                    0.5f, RgbColor.Black, LineStyle.Dots));
                elements.Add(new Line(startPos + (float)Value2 * dotSize,
                                    currentYOffset - BarHeight * 1.5f,
                                    startPos + (float)Value2 * dotSize,
                                    currentYOffset - BarHeight * 4.5f,
                                    0.5f, RgbColor.Black, LineStyle.Dots));
                currentYOffset = Top - BarHeight / 2;
                elements.Add(new Line(startPos, currentYOffset, startPos, currentYOffset + BarHeight * 3 + firstBarVerticalGap + secondBarVerticalGap, 0.5f, Colors.LineColor));
            }
            else
            {
                elements.Add(new Line(startPos + (float)Value2 * dotSize, currentYOffset, startPos + (float)Value1 * dotSize, currentYOffset, BarHeight / 2, thirdBarColor));
                currentYOffset = Top - BarHeight / 2;
                elements.Add(new Line(startPos,
                                    currentYOffset,
                                    startPos,
                                    currentYOffset + BarHeight * 2f + firstBarVerticalGap + secondBarVerticalGap / 2,
                                    0.5f, Colors.LineColor));
                elements.Add(new Line(startPos + (float)Value2 * dotSize,
                                    currentYOffset + BarHeight + firstBarVerticalGap,
                                    startPos + (float)Value2 * dotSize,
                                    currentYOffset + BarHeight * 2.75f + firstBarVerticalGap + secondBarVerticalGap,
                                    0.5f, Colors.LineColor));
                elements.Add(new Line(startPos + (float)Value1 * dotSize,
                                    currentYOffset,
                                    startPos + (float)Value1 * dotSize,
                                    currentYOffset + BarHeight * 2.75f + firstBarVerticalGap + secondBarVerticalGap,
                                    0.5f, Colors.LineColor));
                elements.Add(new Line(Left + 10,
                                    currentYOffset + BarHeight * 2f + firstBarVerticalGap + secondBarVerticalGap / 2,
                                    startPos + chartMaxWidth,
                                    currentYOffset + BarHeight * 2f + firstBarVerticalGap + secondBarVerticalGap / 2,
                                    0.5f, Colors.LineColor));

                var diff = Value2 - Value1;
                LeftBar = diff < 0 ? startPos + (float)Value2 * dotSize : startPos + (float)Value1 * dotSize;
                TopBar = currentYOffset + BarHeight * 2.75f + firstBarVerticalGap + secondBarVerticalGap;
            }

            return elements;
        }

        public override void Draw(PageWriter writer)
        {
            if (_elements == null)
                Render();

            writer.Write_q_(true);
            _elements.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
